using System;
using System.Collections.Generic;
using Blog.Infrastructure.DataAcces.Repositories.Abstractisations;
using NHibernate;
using NHibernate.Criterion;

namespace Blog.Infrastructure.DataAcces.Repositories.Implementaions
{
    public class Repository<T> : IRepository<T>
    {
       protected readonly ISession _session;

        public Repository(ISessionFactory sessionFactory)
        {
            _session = sessionFactory.OpenSession();
        }

        #region IRepository<T> Members

        public IList<T> GetAll()
        {
            return _session.CreateCriteria(typeof(T)).List<T>();
        }

        public IList<T> GetAll(List<long> ids)
        {
            return _session.CreateCriteria(typeof (T))
                .Add(Restrictions.In("Id",ids)).List<T>();
        }

        public T Get(long id)
        {
            return _session.Get<T>(id);
        }

        public T Get(string title)
        {
           return (T)_session.CreateCriteria(typeof(T))
                .Add(Restrictions.Eq("Title", title)).UniqueResult();
        }

        public void Save(T item)
        {
            InSessionDo(session => session.SaveOrUpdate(item));
        }

        public void Delete(long id)
        {
            InSessionDo(session =>
                                {
                                    var entity = session.Get<T>(id);
                                    session.Delete(entity);
                                });
        }
        
        public int Count()
        {
            return _session.CreateCriteria(typeof (T)).List<T>().Count;
        }

        #endregion


        private void InSessionDo(Action<ISession> action)
        {
            action.Invoke(_session);
            _session.Flush();
        }
    }
}